#include <httpResponse.h>
#include <fstream>
#include <exception>
#include <cstring>
#include <regex>

namespace http {

    StringMap httpResponse::fileTypeMap;

    void httpResponse::InitFileTypesMap(std::string filepath) {
        std::fstream infile;
        infile.open(filepath);
        if (!infile) {
            throw std::logic_error("未找到该文件:" + filepath);
        }
        char line[128];
        do {
            memset(line, 0, sizeof(line));
            infile.getline(line, sizeof(line));
            try {
                std::regex regex_comma(",");
                if (std::regex_search(line, regex_comma)) {
                    char *post = strchr(line, ',');
                    fileTypeMap.insert(std::make_pair(std::string(line, post), std::string(post + 1)));
                }
            }
            catch (const std::exception &e) {
                std::cerr << "get" << e.what() << '\n';
            }

        } while (infile);
        infile.close();
    }

    inline void httpResponse::heardAdd(const std::string &key, const std::string &value) {
        heard[key] = value;
    }

    void httpResponse::setCookie(const std::string &cookie) {
        heard["Set-Cookie"] = "login=" + cookie;
    }

    httpResponse::httpResponse(std::string version, std::string code) : version(version), code(code), charset("utf-8"), fileType("text/html") {
    }

    httpResponse::~httpResponse() {
    }

    void httpResponse::setBody(const char *buff, size_t buff_size) {
        if (text != "") text.clear();
        body.assign(buff, buff_size);
        heard["Content-Length"] = std::to_string(buff_size);
    }

    std::string &httpResponse::operator[](std::string key) {
        if (text != "") text.clear();
        return heard[key];
    }

    void httpResponse::setFileType(std::string fileName) {
        auto post = fileName.rfind('.');
        if (post == std::string::npos) {
            return;
        }
        analyseType(fileName.substr(post));
    }

    void httpResponse::analyseType(std::string type) {
        fileType = fileTypeMap[type];
        if (fileType == "")
            fileType = fileTypeMap[".*"];
    }

    std::string &httpResponse::toText() {
        if (text != "") return text;
        text.append(version + " " + code + CRLF);

        heard["Data"]         = date::Date::now().toString();
        heard["Content-Type"] = fileType + "; " + charset;
        for (auto &&i : heard) {
            text.append(i.first + ": " + i.second + CRLF);
        }
        text.append(CRLF + body);
        return text;
    }

}  // namespace http
